"use strict";
/**
 * 从微信接收消息
 * Created by liamjung on 2018/6/27.
 */
const {ResponseWxError} = require("../error/response_wx_error");
const {ResponseError} = require("@libfintech/api-gateway-core/error/response_error");
const {getMpConfig} = require("@libfintech/api-gateway-core/util/util");
const wechat = require("co-wechat");
const router = require("../router/receiving_router");

const MIDDLEWARES = {};

async function getMiddleware(mpId) {

    let middleware = MIDDLEWARES[mpId];

    if (!middleware) {

        let mpConfig = await getMpConfig(mpId);

        if (mpConfig) {

            middleware = wechat({
                //微信的token、appId、aesKey一旦确定不会改变，所以middleware采用缓存机制
                token: mpConfig.token,
                appid: mpConfig.appId,
                encodingAESKey: mpConfig.aesKey
            }).middleware(async (wxMsg, ctx) => {

                ctx.pipeline.logger.debug(JSON.stringify(wxMsg));

                //设置微信消息对象，用于微信网关响应插件中
                ctx.weixin_msg = wxMsg;

                //回复空字符串，实际的回复在response插件中构造
                let outWxMsg = "";

                try {
                    //路由到相应服务
                    await router(wxMsg, ctx.pipeline);
                } catch (err) {

                    if (err instanceof ResponseWxError) {
                        //直接响应微信
                        outWxMsg = err.message;

                        //设置直接响应微信标识
                        ctx.responseWxTag = true;
                    } else {
                        throw err;
                    }
                }

                return outWxMsg;
            });

            MIDDLEWARES[mpId] = middleware;
        }
    }

    return middleware;
}

module.exports = async function (pipeline) {

    let req = pipeline.request;

    let mpId = req.originalPath.substring(req.originalPath.lastIndexOf("/") + 1);

    let middleware = await getMiddleware(mpId);

    if (!middleware) {
        //中间件不存在时，抛出异常

        pipeline.logger.warn("mp config (mpId: " + mpId + ") not existed");

        throw new ResponseError(404);
    }

    await middleware(pipeline.ctx);

    if (pipeline.ctx.responseWxTag) {
        //表示直接响应微信
        throw new ResponseError(200, pipeline.ctx.response.headers, pipeline.ctx.response.body);
    }

    //用于A/B测试
    pipeline.request.headers["mpid"] = mpId;
    pipeline.request.headers["openid"] = pipeline.ctx.weixin_msg.FromUserName;
};